home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch7 / Filter.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-04-30  |  31.5 KB  |  956 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmFilter 
  4.    Caption         =   "Filter []"
  5.    ClientHeight    =   3090
  6.    ClientLeft      =   165
  7.    ClientTop       =   735
  8.    ClientWidth     =   5145
  9.    LinkTopic       =   "Form2"
  10.    ScaleHeight     =   3090
  11.    ScaleWidth      =   5145
  12.    StartUpPosition =   3  'Windows Default
  13.    Begin MSComDlg.CommonDialog dlgOpenFile 
  14.       Left            =   2760
  15.       Top             =   0
  16.       _ExtentX        =   847
  17.       _ExtentY        =   847
  18.       _Version        =   393216
  19.    End
  20.    Begin VB.PictureBox picOriginal 
  21.       AutoSize        =   -1  'True
  22.       Height          =   2775
  23.       Left            =   120
  24.       ScaleHeight     =   181
  25.       ScaleMode       =   3  'Pixel
  26.       ScaleWidth      =   157
  27.       TabIndex        =   1
  28.       Top             =   240
  29.       Width           =   2415
  30.    End
  31.    Begin VB.PictureBox picResult 
  32.       Height          =   2775
  33.       Left            =   2640
  34.       ScaleHeight     =   181
  35.       ScaleMode       =   3  'Pixel
  36.       ScaleWidth      =   157
  37.       TabIndex        =   0
  38.       Top             =   240
  39.       Width           =   2415
  40.    End
  41.    Begin VB.Label lblFilterType 
  42.       Alignment       =   2  'Center
  43.       Height          =   255
  44.       Left            =   2640
  45.       TabIndex        =   2
  46.       Top             =   0
  47.       Width           =   2415
  48.    End
  49.    Begin VB.Menu mnuFile 
  50.       Caption         =   "&File"
  51.       Begin VB.Menu mnuFileOpen 
  52.          Caption         =   "&Open..."
  53.          Shortcut        =   ^O
  54.       End
  55.       Begin VB.Menu mnuFileSaveAs 
  56.          Caption         =   "Save &As..."
  57.          Shortcut        =   ^A
  58.       End
  59.    End
  60.    Begin VB.Menu mnuFilter 
  61.       Caption         =   "Fil&ter"
  62.       Begin VB.Menu mnuFilterIdentity 
  63.          Caption         =   "&Identity"
  64.       End
  65.       Begin VB.Menu mnuFilterLowPass 
  66.          Caption         =   "&Low Pass"
  67.          Begin VB.Menu mnuLowPass 
  68.             Caption         =   "&3x3 Uniform"
  69.             Index           =   3
  70.          End
  71.          Begin VB.Menu mnuLowPass 
  72.             Caption         =   "&5x5 Uniform"
  73.             Index           =   5
  74.          End
  75.          Begin VB.Menu mnuLowPass 
  76.             Caption         =   "&7x7 Uniform"
  77.             Index           =   7
  78.          End
  79.          Begin VB.Menu mnuLowPassSep1 
  80.             Caption         =   "-"
  81.          End
  82.          Begin VB.Menu mnuFilterLowPassPeaked 
  83.             Caption         =   "3x3 Peaked"
  84.             Index           =   3
  85.          End
  86.          Begin VB.Menu mnuFilterLowPassPeaked 
  87.             Caption         =   "5x5 Peaked"
  88.             Index           =   5
  89.          End
  90.          Begin VB.Menu mnuFilterLowPassPeaked 
  91.             Caption         =   "7x7 Peaked"
  92.             Index           =   7
  93.          End
  94.          Begin VB.Menu mnuLowPassSep2 
  95.             Caption         =   "-"
  96.          End
  97.          Begin VB.Menu mnuLowPassStrongPeak 
  98.             Caption         =   "&Strongly Peaked"
  99.          End
  100.       End
  101.       Begin VB.Menu mnuFilterHighPass 
  102.          Caption         =   "&High Pass"
  103.          Begin VB.Menu mnuHighPassVeryWeak 
  104.             Caption         =   "3x3 Very Weak"
  105.          End
  106.          Begin VB.Menu mnuHighPassWeak 
  107.             Caption         =   "3x3 &Weak"
  108.          End
  109.          Begin VB.Menu mnuHighPassStrong 
  110.             Caption         =   "3x3 &Strong"
  111.          End
  112.          Begin VB.Menu mnuHighPassVeryStrong 
  113.             Caption         =   "3x3 &Very Strong"
  114.          End
  115.       End
  116.       Begin VB.Menu mnuPrewittGradient 
  117.          Caption         =   "&Prewitt Gradient Edge Detection"
  118.          Begin VB.Menu mnuPrewitt 
  119.             Caption         =   "NW to SE"
  120.             Index           =   0
  121.          End
  122.          Begin VB.Menu mnuPrewitt 
  123.             Caption         =   "N to S"
  124.             Index           =   1
  125.          End
  126.          Begin VB.Menu mnuPrewitt 
  127.             Caption         =   "NE to SW"
  128.             Index           =   2
  129.          End
  130.          Begin VB.Menu mnuPrewitt 
  131.             Caption         =   "E to W"
  132.             Index           =   3
  133.          End
  134.          Begin VB.Menu mnuPrewitt 
  135.             Caption         =   "SE to NW"
  136.             Index           =   4
  137.          End
  138.          Begin VB.Menu mnuPrewitt 
  139.             Caption         =   "S to N"
  140.             Index           =   5
  141.          End
  142.          Begin VB.Menu mnuPrewitt 
  143.             Caption         =   "SW to NE"
  144.             Index           =   6
  145.          End
  146.          Begin VB.Menu mnuPrewitt 
  147.             Caption         =   "W to E"
  148.             Index           =   7
  149.          End
  150.       End
  151.       Begin VB.Menu mnuLaplacianEdgeDetection 
  152.          Caption         =   "&Laplacian Edge Detection"
  153.          Begin VB.Menu mnuLaplacianWeak 
  154.             Caption         =   "&Weak"
  155.          End
  156.          Begin VB.Menu mnuLaplacianStrong 
  157.             Caption         =   "&Strong"
  158.          End
  159.          Begin VB.Menu mnuLaplacianVeryStrong 
  160.             Caption         =   "&Very Strong"
  161.          End
  162.       End
  163.       Begin VB.Menu mnuEmbossing 
  164.          Caption         =   "&Embossing"
  165.       End
  166.       Begin VB.Menu mnuRankFilter 
  167.          Caption         =   "&Rank"
  168.          Begin VB.Menu mnuRank 
  169.             Caption         =   "&1 (Minimum)"
  170.             Index           =   1
  171.          End
  172.          Begin VB.Menu mnuRank 
  173.             Caption         =   "&2"
  174.             Index           =   2
  175.          End
  176.          Begin VB.Menu mnuRank 
  177.             Caption         =   "&3"
  178.             Index           =   3
  179.          End
  180.          Begin VB.Menu mnuRank 
  181.             Caption         =   "&4"
  182.             Index           =   4
  183.          End
  184.          Begin VB.Menu mnuRank 
  185.             Caption         =   "&5 (Median)"
  186.             Index           =   5
  187.          End
  188.          Begin VB.Menu mnuRank 
  189.             Caption         =   "&6"
  190.             Index           =   6
  191.          End
  192.          Begin VB.Menu mnuRank 
  193.             Caption         =   "&7"
  194.             Index           =   7
  195.          End
  196.          Begin VB.Menu mnuRank 
  197.             Caption         =   "&8"
  198.             Index           =   8
  199.          End
  200.          Begin VB.Menu mnuRank 
  201.             Caption         =   "&9 (Maximum)"
  202.             Index           =   9
  203.          End
  204.       End
  205.       Begin VB.Menu mnuErode 
  206.          Caption         =   "Erode"
  207.       End
  208.       Begin VB.Menu mnuDilate 
  209.          Caption         =   "Dilate"
  210.       End
  211.       Begin VB.Menu mnuFilterSep 
  212.          Caption         =   "-"
  213.          Index           =   8
  214.       End
  215.       Begin VB.Menu mnuFilterShowFilter 
  216.          Caption         =   "&Show Filter"
  217.          Enabled         =   0   'False
  218.       End
  219.       Begin VB.Menu mnuFilterCustom 
  220.          Caption         =   "&Define Custom Filter"
  221.       End
  222.    End
  223. Attribute VB_Name = "frmFilter"
  224. Attribute VB_GlobalNameSpace = False
  225. Attribute VB_Creatable = False
  226. Attribute VB_PredeclaredId = True
  227. Attribute VB_Exposed = False
  228. Option Explicit
  229. Private TheKernel() As Single
  230. ' Apply an erosion filter.
  231. Private Sub ApplyErosionFilter()
  232. Dim bound As Integer
  233. Dim input_pixels() As RGBTriplet
  234. Dim result_pixels() As RGBTriplet
  235. Dim black_pixel As RGBTriplet
  236. Dim white_pixel As RGBTriplet
  237. Dim brightness() As Integer
  238. Dim bits_per_pixel As Integer
  239. Dim X As Integer
  240. Dim Y As Integer
  241. Dim i As Integer
  242. Dim j As Integer
  243.     ' Get the kernel's bounds.
  244.     bound = UBound(TheKernel, 1)
  245.     ' Set the white values.
  246.     With white_pixel
  247.         .rgbRed = 255
  248.         .rgbGreen = 255
  249.         .rgbBlue = 255
  250.     End With
  251.     ' Get the pixels from picOriginal.
  252.     GetBitmapPixels picOriginal, input_pixels, bits_per_pixel
  253.     ' Allocate space for the result pixels.
  254.     ReDim result_pixels( _
  255.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  256.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  257.     ' Allocate the brightness values.
  258.     ReDim brightness( _
  259.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  260.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  261.     ' Calculate brightness values.
  262.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  263.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  264.             With input_pixels(X, Y)
  265.                 brightness(X, Y) = CInt(.rgbRed) + .rgbGreen + .rgbBlue
  266.             End With
  267.         Next X
  268.     Next Y
  269.     ' Set the pixel colors. Note that we
  270.     ' must skip the edges because some of
  271.     ' the kernel values would correspond
  272.     ' to pixels off the image.
  273.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  274.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  275.             ' Examine the nearby pixels.
  276.             For i = -bound To bound
  277.                 For j = -bound To bound
  278.                     ' Get the pixel's brightness
  279.                     If brightness(X + i, Y + j) < TheKernel(i, j) Then Exit For
  280.                 Next j
  281.                 If j <= bound Then Exit For
  282.             Next i
  283.             ' See if we stopped early.
  284.             If j <= bound Then
  285.                 result_pixels(X, Y) = black_pixel
  286.             Else
  287.                 result_pixels(X, Y) = white_pixel
  288.             End If
  289.         Next X
  290.     Next Y
  291.     ' Set picResult's pixels.
  292.     SetBitmapPixels picResult, bits_per_pixel, result_pixels
  293.     picResult.Picture = picResult.Image
  294. End Sub
  295. ' Apply a dilation filter.
  296. Private Sub ApplyDilationFilter()
  297. Dim bound As Integer
  298. Dim input_pixels() As RGBTriplet
  299. Dim result_pixels() As RGBTriplet
  300. Dim black_pixel As RGBTriplet
  301. Dim white_pixel As RGBTriplet
  302. Dim brightness() As Integer
  303. Dim bits_per_pixel As Integer
  304. Dim X As Integer
  305. Dim Y As Integer
  306. Dim i As Integer
  307. Dim j As Integer
  308.     ' Get the kernel's bounds.
  309.     bound = UBound(TheKernel, 1)
  310.     ' Set the white values.
  311.     With white_pixel
  312.         .rgbRed = 255
  313.         .rgbGreen = 255
  314.         .rgbBlue = 255
  315.     End With
  316.     ' Get the pixels from picOriginal.
  317.     GetBitmapPixels picOriginal, input_pixels, bits_per_pixel
  318.     ' Allocate space for the result pixels.
  319.     ReDim result_pixels( _
  320.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  321.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  322.     ' Allocate the brightness values.
  323.     ReDim brightness( _
  324.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  325.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  326.     ' Calculate brightness values.
  327.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  328.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  329.             With input_pixels(X, Y)
  330.                 brightness(X, Y) = CInt(.rgbRed) + .rgbGreen + .rgbBlue
  331.             End With
  332.         Next X
  333.     Next Y
  334.     ' Set the pixel colors. Note that we
  335.     ' must skip the edges because some of
  336.     ' the kernel values would correspond
  337.     ' to pixels off the image.
  338.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  339.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  340.             ' Examine the nearby pixels.
  341.             For i = -bound To bound
  342.                 For j = -bound To bound
  343.                     ' Get the pixel's brightness
  344.                     If brightness(X + i, Y + j) >= TheKernel(i, j) Then Exit For
  345.                 Next j
  346.                 If j <= bound Then Exit For
  347.             Next i
  348.             ' See if we stopped early.
  349.             If j <= bound Then
  350.                 result_pixels(X, Y) = white_pixel
  351.             Else
  352.                 result_pixels(X, Y) = black_pixel
  353.             End If
  354.         Next X
  355.     Next Y
  356.     ' Set picResult's pixels.
  357.     SetBitmapPixels picResult, bits_per_pixel, result_pixels
  358.     picResult.Picture = picResult.Image
  359. End Sub
  360. ' Manage the mouse and apply the image.
  361. Private Sub ApplyTheFilter(Optional offset As Variant)
  362.     ' Do nothing if no picture is loaded.
  363.     If picOriginal.Picture = 0 Then Exit Sub
  364.     ' Do nothing if no filter is loaded.
  365.     If Len(lblFilterType.Caption) = 0 Then Exit Sub
  366.     Screen.MousePointer = vbHourglass
  367.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  368.         picResult.BackColor, BF
  369.     DoEvents
  370.     ' Apply the filter.
  371.     If IsMissing(offset) Then offset = 0
  372.     ApplyFilter TheKernel, offset
  373.     Screen.MousePointer = vbDefault
  374. End Sub
  375. ' Arrange the controls.
  376. Private Sub ArrangeControls()
  377.     ' Position the result PictureBox.
  378.     picResult.Move _
  379.         picOriginal.Left + picOriginal.Width + 120, _
  380.         picOriginal.Top, _
  381.         picOriginal.Width, _
  382.         picOriginal.Height
  383.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  384.         picResult.BackColor, BF
  385.     lblFilterType.Move picResult.Left, _
  386.         0, picResult.Width
  387.     ' This makes the image resize itself to
  388.     ' fit the picture.
  389.     picResult.Picture = picResult.Image
  390.     ' Make the form big enough.
  391.     Width = picResult.Left + picResult.Width + _
  392.         Width - ScaleWidth + 120
  393.     Height = picResult.Top + picResult.Height + _
  394.         Height - ScaleHeight + 120
  395.     DoEvents
  396. End Sub
  397. ' Apply a filter to an image.
  398. Private Sub ApplyFilter(kernel() As Single, ByVal offset As Integer)
  399. Dim bound As Integer
  400. Dim input_pixels() As RGBTriplet
  401. Dim result_pixels() As RGBTriplet
  402. Dim bits_per_pixel As Integer
  403. Dim X As Integer
  404. Dim Y As Integer
  405. Dim i As Integer
  406. Dim j As Integer
  407. Dim r As Integer
  408. Dim g As Integer
  409. Dim b As Integer
  410.     ' Get the kernel's bounds.
  411.     bound = UBound(kernel, 1)
  412.     ' Get the pixels from picOriginal.
  413.     GetBitmapPixels picOriginal, input_pixels, bits_per_pixel
  414.     ' Allocate space for the result pixels.
  415.     ReDim result_pixels( _
  416.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  417.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  418.     ' Set the pixel colors. Note that we
  419.     ' must skip the edges because some of
  420.     ' the kernel values would correspond
  421.     ' to pixels off the image.
  422.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  423.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  424.             ' Start with no color.
  425.             r = offset
  426.             g = offset
  427.             b = offset
  428.             ' Apply the kernel values to
  429.             ' the nearby pixels.
  430.             For i = -bound To bound
  431.                 For j = -bound To bound
  432.                     With input_pixels(X + i, Y + j)
  433.                         r = r + .rgbRed * kernel(j, i)
  434.                         g = g + .rgbGreen * kernel(j, i)
  435.                         b = b + .rgbBlue * kernel(j, i)
  436.                     End With
  437.                 Next j
  438.             Next i
  439.             ' Make sure the values are
  440.             ' between 0 and 255.
  441.             If r < 0 Then r = 0
  442.             If r > 255 Then r = 255
  443.             If g < 0 Then g = 0
  444.             If g > 255 Then g = 255
  445.             If b < 0 Then b = 0
  446.             If b > 255 Then b = 255
  447.             ' Set the output pixel value.
  448.             With result_pixels(X, Y)
  449.                 .rgbRed = r
  450.                 .rgbGreen = g
  451.                 .rgbBlue = b
  452.             End With
  453.         Next X
  454.     Next Y
  455.     ' Set picResult's pixels.
  456.     SetBitmapPixels picResult, bits_per_pixel, result_pixels
  457.     picResult.Picture = picResult.Image
  458. End Sub
  459. ' Apply a rank filter to an image.
  460. Private Sub ApplyRankFilter(ByVal rank As Integer)
  461. Dim bound As Integer
  462. Dim brightnesses(1 To 9) As Integer
  463. Dim color_values(1 To 9) As RGBTriplet
  464. Dim tmp_brightness As Integer
  465. Dim tmp_color_value As RGBTriplet
  466. Dim input_pixels() As RGBTriplet
  467. Dim result_pixels() As RGBTriplet
  468. Dim bits_per_pixel As Integer
  469. Dim X As Integer
  470. Dim Y As Integer
  471. Dim idx As Integer
  472. Dim i As Integer
  473. Dim j As Integer
  474. Dim sort_done As Boolean
  475.     ' Get the pixels from picOriginal.
  476.     GetBitmapPixels picOriginal, input_pixels, bits_per_pixel
  477.     ' Allocate space for the result pixels.
  478.     ReDim result_pixels( _
  479.         LBound(input_pixels, 1) To UBound(input_pixels, 1), _
  480.         LBound(input_pixels, 2) To UBound(input_pixels, 2))
  481.     ' Set the pixel colors.
  482.     bound = 1
  483.     For Y = bound To picOriginal.ScaleHeight - 1 - bound
  484.         For X = bound To picOriginal.ScaleWidth - 1 - bound
  485.             ' Load the nearby colors.
  486.             idx = 1
  487.             For i = -bound To bound
  488.                 For j = -bound To bound
  489.                     With input_pixels(X + i, Y + j)
  490.                         brightnesses(idx) = CInt(.rgbRed) + .rgbGreen + .rgbBlue
  491.                     End With
  492.                     color_values(idx) = input_pixels(X + i, Y + j)
  493.                     idx = idx + 1
  494.                 Next j
  495.             Next i
  496.             ' Sort the color values by brightness.
  497.             Do
  498.                 sort_done = True
  499.                 For i = 1 To 8
  500.                     ' See if the i and i+1 entries
  501.                     ' are in the right order.
  502.                     If brightnesses(i) > brightnesses(i + 1) Then
  503.                         ' Swap them.
  504.                         tmp_brightness = brightnesses(i)
  505.                         brightnesses(i) = brightnesses(i + 1)
  506.                         brightnesses(i + 1) = tmp_brightness
  507.                         tmp_color_value = color_values(i)
  508.                         color_values(i) = color_values(i + 1)
  509.                         color_values(i + 1) = tmp_color_value
  510.                         sort_done = False
  511.                     End If
  512.                 Next i
  513.                 If sort_done Then Exit Do
  514.             Loop
  515.             ' Pick the color with the right rank.
  516.             result_pixels(X, Y) = color_values(rank)
  517.         Next X
  518.     Next Y
  519.     ' Set picResult's pixels.
  520.     SetBitmapPixels picResult, bits_per_pixel, result_pixels
  521.     picResult.Picture = picResult.Image
  522. End Sub
  523. ' Copy kernel entries from a variant array of
  524. ' variant arrays into a normal array.
  525. Private Sub VariantToArray(ByVal var As Variant, ByRef arr() As Single)
  526. Dim bound As Integer
  527. Dim i As Integer
  528. Dim j As Integer
  529.     bound = UBound(var) \ 2
  530.     ReDim arr(-bound To bound, -bound To bound)
  531.     For i = -bound To bound
  532.         For j = -bound To bound
  533.             arr(i, j) = var(i + bound)(j + bound)
  534.         Next j
  535.     Next i
  536. End Sub
  537. ' Start in the current directory.
  538. Private Sub Form_Load()
  539.     picOriginal.AutoSize = True
  540.     picOriginal.ScaleMode = vbPixels
  541.     picOriginal.AutoRedraw = True
  542.     picResult.ScaleMode = vbPixels
  543.     picResult.AutoRedraw = True
  544.     dlgOpenFile.CancelError = True
  545.     dlgOpenFile.InitDir = App.Path
  546.     dlgOpenFile.Filter = _
  547.         "Bitmaps (*.bmp)|*.bmp|" & _
  548.         "GIFs (*.gif)|*.gif|" & _
  549.         "JPEGs (*.jpg)|*.jpg;*.jpeg|" & _
  550.         "Icons (*.ico)|*.ico|" & _
  551.         "Cursors (*.cur)|*.cur|" & _
  552.         "Run-Length Encoded (*.rle)|*.rle|" & _
  553.         "Metafiles (*.wmf)|*.wmf|" & _
  554.         "Enhanced Metafiles (*.emf)|*.emf|" & _
  555.         "Graphic Files|*.bmp;*.gif;*.jpg;*.jpeg;*.ico;*.cur;*.rle;*.wmf;*.emf|" & _
  556.         "All Files (*.*)|*.*"
  557. End Sub
  558. ' Apply an offset embossing filter.
  559. Private Sub mnuEmbossing_Click()
  560.     ' Build the kernel.
  561.     VariantToArray Array( _
  562.         Array(1, 0, 0), _
  563.         Array(0, 0, 0), _
  564.         Array(0, 0, -1)), _
  565.         TheKernel
  566.     ' Prepare some controls.
  567.     mnuFilterShowFilter.Enabled = True
  568.     lblFilterType.Caption = "Embossing 3x3"
  569.     ApplyTheFilter 127
  570. End Sub
  571. ' Apply an erosion filter.
  572. Private Sub mnuErode_Click()
  573.     ' Build the kernel.
  574.     VariantToArray Array( _
  575.         Array(127, 127, 127), _
  576.         Array(127, 127, 127), _
  577.         Array(127, 127, 127)), _
  578.         TheKernel
  579.     ' Prepare some controls.
  580.     mnuFilterShowFilter.Enabled = True
  581.     lblFilterType.Caption = "Erosion"
  582.     ' Do nothing if no picture is loaded.
  583.     If picOriginal.Picture = 0 Then Exit Sub
  584.     ' Do nothing if no filter is loaded.
  585.     If Len(lblFilterType.Caption) = 0 Then Exit Sub
  586.     Screen.MousePointer = vbHourglass
  587.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  588.         picResult.BackColor, BF
  589.     DoEvents
  590.     ApplyErosionFilter
  591.     Screen.MousePointer = vbDefault
  592. End Sub
  593. ' Apply a dilation filter.
  594. Private Sub mnuDilate_Click()
  595.     ' Build the kernel.
  596.     VariantToArray Array( _
  597.         Array(127, 127, 127), _
  598.         Array(127, 127, 127), _
  599.         Array(127, 127, 127)), _
  600.         TheKernel
  601.     ' Prepare some controls.
  602.     mnuFilterShowFilter.Enabled = True
  603.     lblFilterType.Caption = "Dilation"
  604.     ' Do nothing if no picture is loaded.
  605.     If picOriginal.Picture = 0 Then Exit Sub
  606.     ' Do nothing if no filter is loaded.
  607.     If Len(lblFilterType.Caption) = 0 Then Exit Sub
  608.     Screen.MousePointer = vbHourglass
  609.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  610.         picResult.BackColor, BF
  611.     DoEvents
  612.     ApplyDilationFilter
  613.     Screen.MousePointer = vbDefault
  614. End Sub
  615. ' Load the indicated file.
  616. Private Sub mnuFileOpen_Click()
  617. Dim file_name As String
  618.     ' Let the user select a file.
  619.     On Error Resume Next
  620.     dlgOpenFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  621.     dlgOpenFile.ShowOpen
  622.     If Err.Number = cdlCancel Then
  623.         Exit Sub
  624.     ElseIf Err.Number <> 0 Then
  625.         Beep
  626.         MsgBox "Error selecting file.", , vbExclamation
  627.         Exit Sub
  628.     End If
  629.     On Error GoTo 0
  630.     Screen.MousePointer = vbHourglass
  631.     DoEvents
  632.     file_name = Trim$(dlgOpenFile.FileName)
  633.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  634.         - Len(dlgOpenFile.FileTitle) - 1)
  635.     Caption = "Filter [" & dlgOpenFile.FileTitle & "]"
  636.     ' Open the original file.
  637.     On Error GoTo LoadError
  638.     picOriginal.Picture = LoadPicture(file_name)
  639.     On Error GoTo 0
  640.     ' Make picResult the same size and position it.
  641.     ArrangeControls
  642.     Screen.MousePointer = vbDefault
  643.     Exit Sub
  644. LoadError:
  645.     Screen.MousePointer = vbDefault
  646.     MsgBox "Error " & Format$(Err.Number) & _
  647.         " opening file '" & file_name & "'" & vbCrLf & _
  648.         Err.Description
  649. End Sub
  650. ' Save the transformed image.
  651. Private Sub mnuFileSaveAs_Click()
  652. Dim file_name As String
  653.     ' Let the user select a file.
  654.     On Error Resume Next
  655.     dlgOpenFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  656.     dlgOpenFile.ShowSave
  657.     If Err.Number = cdlCancel Then
  658.         Exit Sub
  659.     ElseIf Err.Number <> 0 Then
  660.         Beep
  661.         MsgBox "Error selecting file.", , vbExclamation
  662.         Exit Sub
  663.     End If
  664.     On Error GoTo 0
  665.     Screen.MousePointer = vbHourglass
  666.     DoEvents
  667.     file_name = Trim$(dlgOpenFile.FileName)
  668.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  669.         - Len(dlgOpenFile.FileTitle) - 1)
  670.     Caption = "Filter [" & dlgOpenFile.FileTitle & "]"
  671.     ' Save the transformed image into the file.
  672.     On Error GoTo SaveError
  673.     SavePicture picResult.Picture, file_name
  674.     On Error GoTo 0
  675.     Screen.MousePointer = vbDefault
  676.     Exit Sub
  677. SaveError:
  678.     Screen.MousePointer = vbDefault
  679.     MsgBox "Error " & Format$(Err.Number) & _
  680.         " saving file '" & file_name & "'" & vbCrLf & _
  681.         Err.Description
  682. End Sub
  683. ' Let the user define a custom filter.
  684. Private Sub mnuFilterCustom_Click()
  685. Dim bound As Integer
  686. Dim i As Integer
  687. Dim j As Integer
  688. Dim idx As Integer
  689.     frmCustom.Show vbModal
  690.     If Not frmCustom.Canceled Then
  691.         bound = frmCustom.CustomBound
  692.         ReDim TheKernel(-bound To bound, -bound To bound)
  693.         idx = 0
  694.         For i = -bound To bound
  695.             For j = -bound To bound
  696.                 TheKernel(i, j) = CSng(frmCustom.txtCoefficient(idx))
  697.                 idx = idx + 1
  698.             Next j
  699.         Next i
  700.         mnuFilterShowFilter.Enabled = True
  701.         lblFilterType.Caption = "Custom " & _
  702.             Format$(bound) & "x" & Format$(bound)
  703.     End If
  704.     Unload frmCustom
  705. End Sub
  706. Private Sub mnuFilterIdentity_Click()
  707.     ' Create an identity kernel.
  708.     ReDim TheKernel(0 To 0, 0 To 0)
  709.     TheKernel(0, 0) = 1#
  710.     ' Prepare some controls.
  711.     mnuFilterShowFilter.Enabled = True
  712.     lblFilterType.Caption = "Identity"
  713.     ' Apply the filter.
  714.     ApplyTheFilter
  715. End Sub
  716. ' Display the filter coefficients.
  717. Private Sub mnuFilterShowFilter_Click()
  718.     frmShowFilter.PrepareForm TheKernel
  719.     frmShowFilter.Show vbModal
  720. End Sub
  721. ' Apply a strong high pass filter.
  722. Private Sub mnuHighPassStrong_Click()
  723.     ' Build the kernel.
  724.     VariantToArray Array( _
  725.         Array(0, -1, 0), _
  726.         Array(-1, 5, -1), _
  727.         Array(0, -1, 0)), _
  728.         TheKernel
  729.     ' Prepare some controls.
  730.     mnuFilterShowFilter.Enabled = True
  731.     lblFilterType.Caption = "Strong High Pass 3x3"
  732.     ApplyTheFilter
  733. End Sub
  734. ' Apply a very strong high pass filter.
  735. Private Sub mnuHighPassVeryStrong_Click()
  736.     ' Build the kernel.
  737.     VariantToArray Array( _
  738.         Array(-1, -1, -1), _
  739.         Array(-1, 9, -1), _
  740.         Array(-1, -1, -1)), _
  741.         TheKernel
  742.     ' Prepare some controls.
  743.     mnuFilterShowFilter.Enabled = True
  744.     lblFilterType.Caption = "Very Strong High Pass 3x3"
  745.     ApplyTheFilter
  746. End Sub
  747. ' Apply a very weak high pass filter.
  748. Private Sub mnuHighPassVeryWeak_Click()
  749.     ' Build the kernel.
  750.     VariantToArray Array( _
  751.         Array(-1 / 12, -1 / 12, -1 / 12), _
  752.         Array(-1 / 12, 20 / 12, -1 / 12), _
  753.         Array(-1 / 12, -1 / 12, -1 / 12)), _
  754.         TheKernel
  755.     ' Prepare some controls.
  756.     mnuFilterShowFilter.Enabled = True
  757.     lblFilterType.Caption = "Weak High Pass 3x3"
  758.     ApplyTheFilter
  759. End Sub
  760. ' Apply a weak high pass filter.
  761. Private Sub mnuHighPassWeak_Click()
  762.     ' Build the kernel.
  763.     VariantToArray Array( _
  764.         Array(-1 / 4, -1 / 4, -1 / 4), _
  765.         Array(-1 / 4, 12 / 4, -1 / 4), _
  766.         Array(-1 / 4, -1 / 4, -1 / 4)), _
  767.         TheKernel
  768.     ' Prepare some controls.
  769.     mnuFilterShowFilter.Enabled = True
  770.     lblFilterType.Caption = "Weak High Pass 3x3"
  771.     ApplyTheFilter
  772. End Sub
  773. ' Apply a weak Laplacian edge detection filter.
  774. Private Sub mnuLaplacianWeak_Click()
  775.     ' Build the kernel.
  776.     VariantToArray Array( _
  777.         Array(0, -1, 0), _
  778.         Array(-1, 4, -1), _
  779.         Array(0, -1, 0)), _
  780.         TheKernel
  781.     ' Prepare some controls.
  782.     mnuFilterShowFilter.Enabled = True
  783.     lblFilterType.Caption = "Weak Laplacian 3x3"
  784.     ApplyTheFilter
  785. End Sub
  786. ' Apply a strong Laplacian edge detection filter.
  787. Private Sub mnuLaplacianStrong_Click()
  788.     ' Build the kernel.
  789.     VariantToArray Array( _
  790.         Array(-1, -1, -1), _
  791.         Array(-1, 8, -1), _
  792.         Array(-1, -1, -1)), _
  793.         TheKernel
  794.     ' Prepare some controls.
  795.     mnuFilterShowFilter.Enabled = True
  796.     lblFilterType.Caption = "Strong Laplacian 3x3"
  797.     ApplyTheFilter
  798. End Sub
  799. ' Apply a very strong Laplacian edge detection filter.
  800. Private Sub mnuLaplacianVeryStrong_Click()
  801.     ' Build the kernel.
  802.     VariantToArray Array( _
  803.         Array(-1, -2, -1), _
  804.         Array(-2, 12, -2), _
  805.         Array(-1, -2, -1)), _
  806.         TheKernel
  807.     ' Prepare some controls.
  808.     mnuFilterShowFilter.Enabled = True
  809.     lblFilterType.Caption = "Very Strong Laplacian 3x3"
  810.     ApplyTheFilter
  811. End Sub
  812. ' Apply a low pass filter.
  813. Private Sub mnuLowPass_Click(Index As Integer)
  814. Dim bound As Integer
  815. Dim i As Integer
  816. Dim j As Integer
  817.     ' Build the kernel.
  818.     bound = (Index - 1) \ 2
  819.     ReDim TheKernel(-bound To bound, -bound To bound)
  820.     For i = -bound To bound
  821.         For j = -bound To bound
  822.             TheKernel(i, j) = 1 / (Index * Index)
  823.         Next j
  824.     Next i
  825.     ' Prepare some controls.
  826.     mnuFilterShowFilter.Enabled = True
  827.     lblFilterType.Caption = "Identity"
  828.     ' Apply the filter.
  829.     lblFilterType.Caption = "Low Pass " & _
  830.         Format$(Index) & "x" & _
  831.         Format$(Index)
  832.     ApplyTheFilter
  833. End Sub
  834. ' Apply a peaked low pass filter.
  835. Private Sub mnuFilterLowPassPeaked_Click(Index As Integer)
  836. Dim bound As Integer
  837. Dim i As Integer
  838. Dim j As Integer
  839. Dim total_weight As Integer
  840.     ' Build the kernel.
  841.     bound = (Index - 1) \ 2
  842.     ReDim TheKernel(-bound To bound, -bound To bound)
  843.     For i = -bound To bound
  844.         For j = -bound To bound
  845.             TheKernel(i, j) = 2 * bound + 1 - Abs(i) - Abs(j)
  846.             total_weight = total_weight + TheKernel(i, j)
  847.         Next j
  848.     Next i
  849.     ' Adjust the kernel so the sum of the
  850.     ' coefficients is 1.
  851.     For i = -bound To bound
  852.         For j = -bound To bound
  853.             TheKernel(i, j) = TheKernel(i, j) / total_weight
  854.         Next j
  855.     Next i
  856.     ' Prepare some controls.
  857.     mnuFilterShowFilter.Enabled = True
  858.     lblFilterType.Caption = "Low Pass Peaked " & _
  859.         Format$(Index) & "x" & _
  860.         Format$(Index)
  861.     ApplyTheFilter
  862. End Sub
  863. ' Apply a stongly peaked low pass filter.
  864. Private Sub mnuLowPassStrongPeak_Click()
  865. Dim i As Integer
  866. Dim j As Integer
  867.     ' Build the kernel.
  868.     ReDim TheKernel(-1 To 1, -1 To 1)
  869.     For i = -1 To 1
  870.         For j = -1 To 1
  871.             TheKernel(i, j) = 1 / 20
  872.         Next j
  873.     Next i
  874.     TheKernel(0, 0) = 12 / 20
  875.     ' Prepare some controls.
  876.     mnuFilterShowFilter.Enabled = True
  877.     lblFilterType.Caption = "Strongly Peaked 3x3"
  878.     ApplyTheFilter
  879. End Sub
  880. ' Apply a Prewitt edge detector.
  881. Private Sub mnuPrewitt_Click(Index As Integer)
  882. Dim i As Integer
  883. Dim j As Integer
  884.     ' Build the kernel.
  885.     Select Case Index
  886.         Case 0  ' NW to SE
  887.             VariantToArray Array( _
  888.                 Array(1, 1, 1), _
  889.                 Array(1, -2, -1), _
  890.                 Array(1, -1, -1)), _
  891.                 TheKernel
  892.         Case 1  ' N to S
  893.             VariantToArray Array( _
  894.                 Array(1, 1, 1), _
  895.                 Array(1, -2, 1), _
  896.                 Array(-1, -1, -1)), _
  897.                 TheKernel
  898.         Case 2  ' NE to SW
  899.             VariantToArray Array( _
  900.                 Array(1, 1, 1), _
  901.                 Array(-1, -2, 1), _
  902.                 Array(-1, -1, 1)), _
  903.                 TheKernel
  904.         Case 3  ' E to W
  905.             VariantToArray Array( _
  906.                 Array(-1, 1, 1), _
  907.                 Array(-1, -2, 1), _
  908.                 Array(-1, 1, 1)), _
  909.                 TheKernel
  910.         Case 4  ' SE to NW
  911.             VariantToArray Array( _
  912.                 Array(-1, -1, 1), _
  913.                 Array(-1, -2, 1), _
  914.                 Array(1, 1, 1)), _
  915.                 TheKernel
  916.         Case 5  ' S to N
  917.             VariantToArray Array( _
  918.                 Array(-1, -1, -1), _
  919.                 Array(1, -2, 1), _
  920.                 Array(1, 1, 1)), _
  921.                 TheKernel
  922.         Case 6  ' SW to NE
  923.             VariantToArray Array( _
  924.                 Array(1, -1, -1), _
  925.                 Array(1, -2, -1), _
  926.                 Array(1, 1, 1)), _
  927.                 TheKernel
  928.         Case 7  ' W to E
  929.             VariantToArray Array( _
  930.                 Array(1, 1, -1), _
  931.                 Array(1, -2, -1), _
  932.                 Array(1, 1, -1)), _
  933.                 TheKernel
  934.     End Select
  935.     ' Prepare some controls.
  936.     mnuFilterShowFilter.Enabled = True
  937.     lblFilterType.Caption = "Prewitt " & _
  938.         mnuPrewitt(Index).Caption
  939.     ApplyTheFilter
  940. End Sub
  941. ' Apply a rank filter.
  942. Private Sub mnuRank_Click(Index As Integer)
  943.     ' Prepare some controls.
  944.     mnuFilterShowFilter.Enabled = True
  945.     lblFilterType.Caption = "Rank " & Format$(Index)
  946.     ' Do nothing if no picture is loaded.
  947.     If picOriginal.Picture = 0 Then Exit Sub
  948.     Screen.MousePointer = vbHourglass
  949.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  950.         picResult.BackColor, BF
  951.     DoEvents
  952.     ' Apply the filter.
  953.     ApplyRankFilter Index
  954.     Screen.MousePointer = vbDefault
  955. End Sub
  956.